namespace ScrumSprintMonitor.TestbenchApp
{
	#region #using Directives

	using System;
	using System.Diagnostics.CodeAnalysis;

	using Design;

	using Implementation;
	using Implementation.AvailableTimeCalculator;
	using Implementation.Configuration;

	using Infrastructure;
	using Infrastructure.Configuration;

	using Ninject.Core;
	using Ninject.Core.Behavior;

	using Rhino.Mocks;

	using Testbench.Impl;

	using UI.Wpf;

	#endregion

	[SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
		Justification = "The NinjectContainerAbstraction will create this class")]
	internal class NinjectAppConfigurationDependentModule : StandardModule
	{
		/// <summary>
		/// Loads the module into the kernel.
		/// </summary>
		public override void Load()
		{
			SetupRuntimeBindings();
		}

		private void SetupRuntimeBindings()
		{
			var connection = Kernel.Get<IConnection>();

			Bind<IBuildInfo>().To<TestBuildInfo>();
			Bind<IReportableData>().To<ReportableData>().Using<SingletonBehavior>().WithArgument("connection", connection);
			Bind<ISprint>().To<Sprint>().WithArgument("connection", connection);
			Bind<ISprintBurndown>().To<SprintBurndown>();
			Bind<ITeamMember>().To<TeamMember>();
			Bind<ITeamMemberRemainingWorkload>().To<TeamMemberRemainingWorkload>();
			Bind<IRemainingWorkStatusEvaluator>().To<RemainingWorkStatusEvaluator>().Using<SingletonBehavior>();
			/*if (Settings.Default.EnableOutlookIntegration)
			{
				Bind<ITeamMemberAvailableTimeCalculator>().To<FreeBusyTeamMemberAvailableTimeCalculator>().Using<SingletonBehavior>();
				Bind<ITeamMemberFreeBusyInfo>().To<TeamMemberOutlookFreeBusyInfo>().Using<SingletonBehavior>();
				Bind<IFreeBusyInfoConfiguration>().To<OutlookFreeBusyInfoConfiguration>().Using<SingletonBehavior>();
			}
			else*/
			{
				var freeBusyInfoConfig = MockRepository.GenerateStub<IFreeBusyInfoConfiguration>();
				freeBusyInfoConfig.Stub(m => m.ExcludeWeekends).Return(true);
				Bind<IFreeBusyInfoConfiguration>().ToConstant(freeBusyInfoConfig);

				Bind<ITeamMemberAvailableTimeCalculator>().To<SimpleTeamMemberAvailableTimeCalculator>().Using<SingletonBehavior>();
				Bind<ITeamMemberFreeBusyInfo>().ToConstant(new TeamMemberFreeBusyInfo(freeBusyInfoConfig));
			}

			var workItemInterpretationConfiguration = new WorkItemInterpretationConfiguration
			                                          	{
			                                          		AllowUnestimatedWorkItems = true
			                                          	};
			Bind<IWorkItemInterpretationConfiguration>().ToConstant(workItemInterpretationConfiguration);

			var shellLayoutConfiguration = new ShellLayoutConfiguration(true, false, true, SprintMode.Sprinting);
			Bind<IShellLayoutConfiguration>().ToConstant(shellLayoutConfiguration);

			SetupConfigurationBindings();
			SetupPresentationSettingsBindings();
			SetupTeamInformationBindings();
		}

		private void SetupPresentationSettingsBindings()
		{
			//string fullPath = Path.GetFullPath(Settings.Default.PresentationConfigurationFilePath);

			//if (!File.Exists(fullPath))
			//{
			//    throw new FileNotFoundException(
			//        string.Format("Could not find the presentation settings file at {0}.", Settings.Default.TeamMembersConfigurationFilePath), fullPath);
			//}

			Bind<IPresentationConfiguration>().To<TestAssetLibrary.HardcodedPresentationConfiguration>().Using<SingletonBehavior>();
			//Bind<IPresentationConfiguration>().To<StreamBasedPresentationConfiguration>().Using<SingletonBehavior>().WithArgument("streamProvider",
			//                                                                                                                      new ConfigurationFileStreamProvider
			//                                                                                                                        (fullPath));
		}

		private void SetupConfigurationBindings()
		{
			//string fullPath = Path.GetFullPath(Settings.Default.ConfigurationFilePath);

			//if (!File.Exists(fullPath))
			//{
			//    throw new FileNotFoundException(
			//        string.Format("Could not find the configuration file at {0}.", Settings.Default.TeamMembersConfigurationFilePath), fullPath);
			//}

			var sprintConfiguration = TestAssetLibrary.CreateSprintConfiguration();
			sprintConfiguration.SprintStartDate = new DateTime(2009, 08, 10, 8, 0, 0);
			sprintConfiguration.SprintEndDate = new DateTime(2009, 08, 24, 17, 0, 0);
			Bind<ISprintConfiguration>().ToConstant(sprintConfiguration);
		}

		private void SetupTeamInformationBindings()
		{
			//string fullPath = Path.GetFullPath(Settings.Default.TeamMembersConfigurationFilePath);

			//if (!File.Exists(fullPath))
			//{
			//    throw new FileNotFoundException(
			//        string.Format("Could not find the team information xml file at {0}.", Settings.Default.TeamMembersConfigurationFilePath), fullPath);
			//}

			//IDataStreamProvider xsdStreamProvider = null;
			//string xsdPath = Path.Combine(Path.GetDirectoryName(Settings.Default.TeamMembersConfigurationFilePath), @"team-info.xsd");
			//if (!File.Exists(xsdPath))
			//{
			//    xsdPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"team-info.xsd");
			//}
			//if (File.Exists(xsdPath))
			//{
			//    xsdStreamProvider = new ConfigurationFileStreamProvider(xsdPath);
			//}
			//var teamMemberInfoProviderParams = new Dictionary<string, object>
			//                                    {
			//                                        {"xmlStreamProvider", new ConfigurationFileStreamProvider(fullPath)},
			//                                        {"xsdStreamProvider", xsdStreamProvider}
			//                                    };

			//Bind<ITeamMemberInfoProvider>().To<XmlStreamBasedTeamInfoProvider>().Using<SingletonBehavior>().WithArguments(teamMemberInfoProviderParams);

			//Bind<ITeamMemberInformation>().To<TeamMemberInformation>();
			Bind<ITeamMemberInfoProvider>().ToConstant(TestAssetLibrary.CreateTeamMemberInfoProvider());
		}
	}
}